﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Nucleic.Core.WeiXinMp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Nucleic.Core.Utils
{
    public class WeiXinUtil
    {
        private static readonly string tokenUrl = "https://api.weixin.qq.com/cgi-bin/token";
        private static readonly string ticket = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
        private const string userSubscribeInfoUrl = "https://api.weixin.qq.com/cgi-bin/user/info";
        private const string userWebAuthAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token";

        public static string GetAccessToken(string appId, string secret)
        {
            StringBuilder sbUrl = new StringBuilder();
            sbUrl.AppendFormat(tokenUrl);
            sbUrl.AppendFormat("?grant_type=client_credential");
            sbUrl.AppendFormat("&appid={0}", appId);
            sbUrl.AppendFormat("&secret={0}", secret);
            using (WebClient client = new WebClient())
            {
                client.Encoding = Encoding.UTF8;
                string data = client.UploadString(sbUrl.ToString(), string.Empty);
                var result = JObject.Parse(data);
                if (result["access_token"] != null && result["access_token"].Value<string>() != string.Empty)
                {
                    string token = result["access_token"].Value<string>();
                    return token;
                }
                else
                {
                    return "";
                }
            }
        }
        public static string GetTicket(string accessToken)
        {
            StringBuilder sbUrl = new StringBuilder();
            sbUrl.AppendFormat(ticket);
            sbUrl.AppendFormat("?access_token={0}", accessToken);
            sbUrl.AppendFormat("&type=jsapi");
            using (WebClient client = new WebClient())
            {
                client.Encoding = Encoding.UTF8;
                string data = client.UploadString(sbUrl.ToString(), string.Empty);
                var result = JObject.Parse(data);
                if (result["ticket"] != null && result["ticket"].Value<string>() != string.Empty)
                {
                    string ticket = result["ticket"].Value<string>();
                    return ticket;
                }
                else
                {
                    return "";
                }
            }
        }
        /// <summary>
        /// 获取签名
        /// </summary>
        /// <param name="timestamp"></param>
        /// <param name="noncestr"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string GetSignature(string timestamp, string noncestr, string url, string appId, string secret)
        {
            string jsticket = GetTicket(GetAccessToken(appId, secret));
            string string1 = "jsapi_ticket=" + jsticket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + url;
            string sig;
            //使用sha1加密这个字符串
            using (SHA1 sha1Hash = SHA1.Create())
            {
                byte[] sourceBytes = Encoding.UTF8.GetBytes(string1);
                byte[] hashBytes = sha1Hash.ComputeHash(sourceBytes);
                sig = BitConverter.ToString(hashBytes).Replace("-", String.Empty);
            }
            return sig;
        }
        /// <summary>
        /// 生成随机字符串
        /// </summary>
        /// <returns></returns>
        public static string CreateNonceStr()
        {
            int length = 16;
            string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            string str = "";
            var rad = new Random();
            for (int i = 0; i < length; i++)
            {
                str += chars.Substring(rad.Next(0, chars.Length - 1), 1);
            }
            return str;
        }
        /// <summary>
        /// 生成时间戳
        /// </summary>
        /// <returns></returns>
        public static string CreateTimestamp()
        {
            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            string timestamp = Convert.ToInt64(ts.TotalSeconds).ToString();
            return timestamp;
        }

        /// <summary>
        /// 消息推送
        /// </summary>
        /// <param name="Access_token">网页授权凭证，通过微信接口获取</param>
        /// <param name="Openid">要推送的用户oppenid</param>
        /// <returns></returns>
        public string MsgPush(string Access_token, string Openid,object data,string url)
        {
            string templateId = "QJM7zs35eByqO7Ys4lzeDCa6354wzRoIJgKYl2-GzVM";//模板编号
           
            var d = new
            {
                touser = Openid,
                template_id = templateId,
                url = url,
                data = data
            };
            string result = WeChatPushNotice(Access_token, JsonConvert.SerializeObject(d));

            return result;
        }
        /// <summary>
        ///微信消息推送
        /// </summary>
        /// <param name="accessToken">微信access_token</param>
        /// <param name="contentMsg">推送内容</param>
        /// <returns></returns>
        public string WeChatPushNotice(string accessToken, string contentMsg)
        {
            string promat = "";
            //需要提交的数据
            byte[] bs = Encoding.UTF8.GetBytes(contentMsg);
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken + "");
            req.Method = "POST";
            req.ContentType = "application/x-www-form-urlencoded";
            req.ContentLength = bs.Length;
            using (Stream reqStream = req.GetRequestStream())
            {
                reqStream.Write(bs, 0, bs.Length);
            }
            HttpWebResponse respon = (HttpWebResponse)req.GetResponse();
            Stream stream = respon.GetResponseStream();
            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                promat = reader.ReadToEnd();
            }
            ReturnMsg y = JsonConvert.DeserializeObject<ReturnMsg>(promat);
            promat = y.errmsg;

            return promat;

        }
        /// <summary>
        /// 自定义模型
        /// </summary>
        private class ReturnMsg
        {
            public string errcode { get; set; }
            public string errmsg { get; set; }
            public string msgid { get; set; }
        }
    }
}
